package com.xb.loan.cashier.biz.job;

import com.xb.loan.cashier.biz.dao.bean.CashierPayChannel;
import com.xb.loan.cashier.biz.service.CashierPayChannelService;
import com.xb.loan.cashier.biz.util.Configure;
import com.xb.loan.cashier.service.constant.ICashierEnumConst;
import com.xb.loan.util.qrtz.TaskScheduleManager;
import com.xb.loan.util.qrtz.task.AbstractCronTask;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**

 提现退票线程（支付宝）
 * 每天凌晨2点，请求支付宝获取退票文件
 * 退票：用户的转账申请通过支付宝提交给银行处理后，银行返回结果是转账成功，支付宝通知用户转账成功（短信通知及支付宝页面更新转账状态），但间隔一段时间后，银行再次通知支付宝转账失败并返还转账款项给支付宝，支付宝再将该笔失败款返还至用户的支付宝账户中。
 * 退票原因：部分银行（如中国邮政储蓄银行）的转账申请需先通过人民银行的支付系统，再由接收行（如中国邮政储蓄银行）入账，此时如存在账号、户名或其他不能入账的原因，接收行会将款项再退回到原汇出行（这里是支付宝）。所以，一笔转账，人民银行的支付系统会先返回成功状态，但是若接收行入账失败，会再次通知转账失败。
 * 参考：https://cshall.alipay.com/lab/help_detail.htm?help_id=212558
 */
public class ThirdAccountEncashRefundAlipayJob extends AbstractCronTask {
    private static final Logger logger = LoggerFactory.getLogger(ThirdAccountEncashRefundAlipayJob.class);
    
    private CashierPayChannelService cashierPayChannelService;
    private String date;
    private static String DATE = "date";

    @Override
    public void run() {
    	logger.info("提现退票线程（支付宝）ThirdAccountEncashRefundAlipayJob初始化参数开始");
        initParams();
        logger.info("提现退票线程（支付宝）ThirdAccountEncashRefundAlipayJob初始化参数结束");
        
        cashierPayChannelService = getSpringBean("cashierPayChannelService");
        TaskScheduleManager manager = getSpringBean("taskScheduleManager");
        //提现才有退票
        List<CashierPayChannel> channels = cashierPayChannelService.selectByPayChannelType(ICashierEnumConst.CashierPayChannelType.ALIPAY.getType(),ICashierEnumConst.CashierPayType.encash.getCode());
        if(channels==null || channels.size() < 1){
            logger.info("支付宝渠道为空，不需要查询退票");
            return;
        }
        
        String filePath = Configure.getStringValue("task.encashrefund.alipay.file.path");
        String signType = ICashierEnumConst.CashierEncryptType.MD5.getDesc();// TODO 默认
        // 中途死掉怎么处理，因为小任务已经在数据库存在了==>抛出异常让任务重新执行，小任务如果是未完成状态重新执行时不会抛出异常
        Map<String, Object> channelJobParams = null;
        for(CashierPayChannel channel : channels){
            ThirdAccountEncashRefundAlipayChannelJob job = new ThirdAccountEncashRefundAlipayChannelJob();
            channelJobParams = new HashMap<String, Object>();
            job.setParams(channelJobParams);
            job.setJobName("ALIPAY_REFUND_"+date+"_"+channel.getPayChannelId());
            channelJobParams.put("cashierPayChannel", channel);
            channelJobParams.put("date", date);
            channelJobParams.put("fileName", date+"_"+channel.getPayChannelId()+".csv");
            channelJobParams.put("filePath", filePath);
            channelJobParams.put("signType", signType);
            manager.shedule(job);
        }
    }

    private void initParams() {
        Map<String, Object> params = getParams();
        if(params==null){
            params = new HashMap<String, Object>();
        }
        date = params.get(DATE)==null?null:params.get(DATE).toString();
        if(StringUtils.isBlank(date)){
            date = new SimpleDateFormat("yyyyMMdd").format(DateUtils.addDays(new Date(), -1));// 默认查询前一天的退票结果
        }
        if(StringUtils.isBlank(date)){
            logger.warn(DATE+"不能为空");
            throw new RuntimeException(DATE+"不能为空");
        }
        params.put(DATE, date);
        setParams(params);
    }
    
    public void setDate(String date) {
        this.date = date;
    }
    
}
